package vip.sweet.sys.modular.role.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import vip.sweet.common.response.CommonPageResponse;
import vip.sweet.sys.modular.resources.entity.Resources;
import vip.sweet.sys.modular.role.entity.Role;
import vip.sweet.sys.modular.role.mapper.RoleMapper;
import vip.sweet.sys.modular.role.params.AddRoleParams;
import vip.sweet.sys.modular.role.params.RoleGrantResourceParams;
import vip.sweet.sys.modular.role.params.RolePageParam;
import vip.sweet.sys.modular.role.service.RoleService;

import java.util.List;
import java.util.stream.Collectors;


/**
 * @author tianlianyin
 * @date 2024/11/11
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Override
    public CommonPageResponse page(RolePageParam pageParam) {
        LambdaQueryWrapper<Role> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        Page<Role> page = new Page<>(pageParam.getPageNum(), pageParam.getPageSize());
        if (ObjectUtil.isNotEmpty(pageParam.getName())) {
            lambdaQueryWrapper.eq(Role::getName, pageParam.getName());
        }
        if (ObjectUtil.isNotEmpty(pageParam.getDepartmentId())) {
            lambdaQueryWrapper.eq(Role::getDepartmentId, pageParam.getDepartmentId());
        }
        Page<Role> pageQuery = page(page, lambdaQueryWrapper);
        return CommonPageResponse.builder()
                .pageNum((int) pageQuery.getCurrent())
                .pageSize((int) pageQuery.getSize())
                .total(pageQuery.getTotal())
                .totalPages((int) pageQuery.getPages())
                .data(pageQuery.getRecords())
                .build();
    }

    @Override
    public boolean add(AddRoleParams addRoleParams) {
        if (ObjectUtil.isNotEmpty(addRoleParams))
            return save(BeanUtil.toBean(addRoleParams, Role.class));
        return false;
    }

    @Override
    public boolean delete(String id) {
        if (ObjectUtil.isNotEmpty(id))
            if (ObjectUtil.isNotEmpty(getById(id)))
                return removeById(id);
        return false;
    }

    @Override
    public boolean edit(Role role) {
        if (ObjectUtil.isNotEmpty(role))
            if (ObjectUtil.isNotEmpty(getById(role.getId())))
                return updateById(role);
        return false;
    }

    @Override
    public List<Resources> getAllResourceById(String id) {
        if (ObjectUtil.isNotEmpty(id)) {
            List<Resources> allResourcesByRoleId = baseMapper.getAllResourcesByRoleId(id);
            List<Resources> resourcesVOS = allResourcesByRoleId.stream().map(
                    resources -> {
                        Resources resourceVO = new Resources();
                        BeanUtils.copyProperties(resources, resourceVO);
                        return resourceVO;
                    }
            ).toList();
            return resourcesVOS.stream().filter(resourceVO -> resourceVO.getParentId().equals("top")).peek(menu -> menu.setChildren(getChildrenData(menu, resourcesVOS))).toList();

        }
        return null;
    }

    @Override
    public boolean grantResource(RoleGrantResourceParams roleGrantResourceParams) {
        if (ObjectUtil.isNotEmpty(roleGrantResourceParams))
            baseMapper.clearResourceByRoleId(roleGrantResourceParams.getRoleId());
        if (ObjectUtil.isEmpty(roleGrantResourceParams.getResourcesIds()))
            return false;
        return baseMapper.grantResource(roleGrantResourceParams.getRoleId(), roleGrantResourceParams.getResourcesIds());
    }

    //获取孩子（下级目录）的方法，递归实现
    private List<Resources> getChildrenData(Resources root, List<Resources> all) {
        return all.stream().filter(subjectVO ->
                subjectVO.getParentId().equals(root.getId())
        ).peek(subjectVO -> subjectVO.setChildren(getChildrenData(subjectVO, all))).collect(Collectors.toList());
    }
}
